package com.vere.rpc.clinet;//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//



import com.vere.rpc.model.RemoteAddress;
import com.vere.rpc.msg.CallMessage;
import com.vere.rpc.proxy.RPCHandler;
import com.vere.rpc.proxy.RPCProxy;
import com.vere.rpc.util.ObjectUtil;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.channels.Selector;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class RemoteClient {
    private Selector selector = null;
    private SocketChannel socketChannel = null;
    private int retries = 1;
    private int retryIndex = 0;
    private List<RemoteAddress> remoteAddressList = new ArrayList();
    private int remoteAddressIndex = 0;

    public RemoteClient() {
        try {
            this.selector = Selector.open();
        } catch (IOException var2) {
            var2.printStackTrace();
        }

    }

    public void setRemoteAddressList(String removeAddressList) {
        this.remoteAddressList.clear();
        String[] masterServerArray = removeAddressList.split(",");
        List<String> masterServerList = Arrays.asList(masterServerArray);

        for(int i = 0; i < masterServerList.size(); ++i) {
            String remoteAddress = (String)masterServerList.get(i);
            this.remoteAddressList.add(new RemoteAddress(remoteAddress, true));
        }

    }

    private RemoteAddress getNextRemoteAddress() {
        if (this.remoteAddressList.size() == 1) {
            return this.retryNextRemoteAddress();
        } else if (this.remoteAddressIndex >= this.remoteAddressList.size()) {
            return null;
        } else {
            RemoteAddress remoteAddress = (RemoteAddress)this.remoteAddressList.get(this.remoteAddressIndex);
            if (!remoteAddress.isConnected()) {
                return this.getNextRemoteAddress();
            } else {
                ++this.remoteAddressIndex;
                return remoteAddress;
            }
        }
    }

    private RemoteAddress retryNextRemoteAddress() {
        if (this.retryIndex < this.retries) {
            RemoteAddress remoteAddress = (RemoteAddress)this.remoteAddressList.get(this.remoteAddressIndex);
            ++this.retryIndex;
            return remoteAddress;
        } else {
            this.retryIndex = 0;
            return null;
        }
    }

    private void threadSleep(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException var4) {
            var4.printStackTrace();
        }

    }

    public void connect() {
        RemoteAddress remoteAddress = this.getNextRemoteAddress();
        if (remoteAddress != null) {
            try {
                this.socketChannel = SocketChannel.open(new InetSocketAddress(remoteAddress.getIp(), remoteAddress.getPort()));
                this.socketChannel.configureBlocking(false);
                this.socketChannel.register(this.selector, 1);
            } catch (Exception var5) {
                try {
                    remoteAddress.setConnected(false);
                    this.connect();
                } catch (Exception var4) {
                    var4.printStackTrace();
                }

                var5.printStackTrace();
            }

        }
    }

    private Object getProxy(Class<?> target) {
        RPCHandler invocationHandler = new RPCHandler(this);
        RPCProxy proxy = new RPCProxy();
        proxy.setRPCHandler(invocationHandler);
        return proxy.getProxy(target);
    }

    public Object getBean(Class<?> target) {
        return this.getProxy(target);
    }

    public void close() {
        try {
            if (this.socketChannel != null) {
                CallMessage callMessage = new CallMessage();
                callMessage.setAction(CallMessage.CLOSE);
                ObjectUtil.sendObject(this.socketChannel, callMessage);
                this.socketChannel.close();
            }
        } catch (IOException var2) {
            var2.printStackTrace();
        }

    }

    public SocketChannel getSocketChannel() {
        return this.socketChannel;
    }

    public Selector getSelector() {
        return this.selector;
    }
}
